﻿using System;
using System.Collections.Generic;
using CID.Execution.Support.Information;

namespace CID.Execution.Support.TemplateHandling
{
    public sealed class TemplateHandlerFactory
    {
        public static readonly TemplateHandlerFactory Instance = new TemplateHandlerFactory();

        private Dictionary<string, Type> templateHandlerTypesMap;
        
        private TemplateHandlerFactory()
        {
            templateHandlerTypesMap = new Dictionary<string, Type>();
        }

        public ITemplateHandler CreateTemplateHandler(TemplateTypeInfo templateType) 
        {
            if (!templateHandlerTypesMap.ContainsKey(templateType.Name))
                throw new TemplateHandlerNotFoundException(templateType);

            return (ITemplateHandler) Activator.CreateInstance(templateHandlerTypesMap[templateType.Name]);
        }

        public void RegisterTemplateHandlerType(string templateTypeName, Type templateHandlerType)
        {
            if (!typeof(ITemplateHandler).IsAssignableFrom(templateHandlerType))
                throw new InvalidCastException(String.Format("Type {0} is not a valid ITemplateHandler", templateHandlerType));
            if (templateHandlerType.IsAbstract || (templateHandlerType.GetConstructor(new Type[0]) == null))
                throw new InvalidCastException(String.Format("Type {0} can't be instantiated with a parameterless constructor", templateHandlerType));

            if (!templateHandlerTypesMap.ContainsKey(templateTypeName))
                templateHandlerTypesMap.Add(templateTypeName, null);

            templateHandlerTypesMap[templateTypeName] = templateHandlerType;
        }

        public void UnregisterTemplateHandlerType(string templateTypeName)
        {
            if (templateHandlerTypesMap.ContainsKey(templateTypeName))
                templateHandlerTypesMap.Remove(templateTypeName);
        }
    }
}
